package com.bjpowernode.config;

import com.bjpowernode.config.filter.TokenVerifyFilter;
import com.bjpowernode.config.handle.MyAuthenticationFailureHandler;
import com.bjpowernode.config.handle.MyAuthenticationSuccessHandler;
import com.bjpowernode.config.handle.MyLogoutSuccessHandler;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.List;

@Configuration
public class SecurityConfig {

    @Autowired
    private MyAuthenticationSuccessHandler successHandler;
    @Autowired
    private MyAuthenticationFailureHandler failureHandler;
    @Autowired
    private TokenVerifyFilter tokenVerifyFilter;
    @Autowired
    private MyLogoutSuccessHandler logoutSuccessHandler;

    /*
    配置跨域
     */
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(List.of("*"));
        configuration.setAllowedMethods(List.of("*"));
        configuration.setAllowedHeaders(List.of("*"));

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);

        return source;
    }

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http, CorsConfigurationSource corsConfigurationSource) throws Exception {
        // 禁用跨域保护
        return http
                .formLogin(formLogin -> {
                    formLogin.loginProcessingUrl("/api/login")
                            .usernameParameter("loginAct")
                            .passwordParameter("loginPwd")
                            .successHandler(successHandler)
                            .failureHandler(failureHandler);
                })
                .authorizeHttpRequests((authorize) -> {
                    authorize.requestMatchers("/api/login").permitAll().
                            anyRequest().authenticated(); // 任何请求都需要拦截
                })
                .csrf(AbstractHttpConfigurer::disable) //禁用跨站伪造请求

                // 支持跨域请求
                .cors((cors) -> {
                    cors.configurationSource(corsConfigurationSource);
                })

                .sessionManagement((session) -> {
                    // session创建策略 禁用
                    session.sessionCreationPolicy(SessionCreationPolicy.STATELESS); // 无session状态
                })

                // 添加自定义Filter
                .addFilterBefore(tokenVerifyFilter, LogoutFilter.class)
                
                // 退出登录
                .logout((logout) ->{
                	logout.logoutUrl("/api/logout") // 退出提交到该地址，该地址不需要我们写controller。是框架处理
                	.logoutSuccessHandler(logoutSuccessHandler);
                })

                .build();
    }
}
